#pragma once
#include<iostream>
#include<vector>
#include<string>
#include<cassert>
#include<algorithm>
#include<cstdint>
#include<cstring>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<functional>
#include<sys/epoll.h>
#include<sys/eventfd.h>
#include<sys/timerfd.h>
#include<thread>
#include<condition_variable>
#include<mutex>
#include<typeinfo>
#include<unordered_map>
#include"log.hpp"

#define MAX_EVENTS 64 //epoll_wait时，从epoll中捞取的最大就绪fd数

//Buffer————客户端与服务器间数据交互的中转站
//Buffer模块存在的意义:
//1.服务器套接字接收来自客户端的数据可能不完整，这时就不能对数据立即处理，而是要先将数据存起来
//2.服务器向客户端发送数据时，通信通道可能已经被写满了，导致数据阻塞，所以应该先将数据存起来，等套接字可写时，再向对方发送数据

//Buffer模块存在的主要功能：
//1.将数据写入缓冲区   2.从缓冲区中拿出数据
class Buffer
{
private:
    std::vector<char> _vv;
    uint64_t _write_pos;//写偏移
    uint64_t _read_pos;//读偏移
public:
    Buffer():_write_pos(0),_read_pos(0){}
    //拷贝构造
    Buffer(const Buffer& bf):_read_pos(bf._read_pos),_write_pos(bf._write_pos),_vv(bf._vv){}
    ~Buffer(){  Close();  };
    //对buffer写入数据
    void WriteData(const void* nums,uint64_t size)
    {
        if(size==0)return;
        EnsureSpaceEnough(size);//确保空间足够
        const char* datas=static_cast<const char*>(nums);//size的单位是byte
        std::copy(datas,datas+size,&_vv[_write_pos]);//数据写入
        _write_pos+=size;//更新写偏移
        //Log(Debug,"%s",datas);
    }
    //从buffer中读取数据，读到buf中
    void ReadData(void* buf,uint64_t size)
    {
        char* bufs=static_cast<char*>(buf);//size的单位是byte
        //确保期望读取长度 < _vv中可读取数据长度
        if(size<=EnableReadSize())
            std::copy(&_vv[_read_pos],&_vv[_read_pos]+size,bufs);
        else 
            std::copy(&_vv[_read_pos],&_vv[_write_pos],bufs);
    }
    //从buffer中读取数据 && 更新读偏移 
    void ReadDataAndPop(void* buf,uint64_t size)
    {
        ReadData(buf,size);
        if(size<=EnableReadSize())
            _read_pos+=size;
        else 
            _read_pos=_write_pos;
    }
    //针对string类型数据设计特殊接口
    std::string ReadDataToString(uint64_t size)
    {
        std::string str;
        str.resize(size);
        //确保期望读取长度 < _vv中可读取数据长度
        if(size<=EnableReadSize())
            std::copy(&_vv[_read_pos],&_vv[_read_pos]+size,&str[0]);
        else 
            std::copy(&_vv[_read_pos],&_vv[_write_pos],&str[0]);
        return str; //右值 
    }
    //将数据读到string类型返回值中，并刷新“写偏移”
    std::string ReadDataToStringAndPop(uint64_t size)
    {
        std::string str=ReadDataToString(size);
        if(size<=EnableReadSize())
            _read_pos+=size;
        else 
            _read_pos=_write_pos;
        return str;
    }
    //返回一行数据
    std::string GetOneLine()
    {
        if(FindCRLF()!=NULL)
            return ReadDataToString(FindCRLF()-&_vv[_read_pos]+1);
        return "";
    }
    //可读数据长度
    uint64_t EnableReadSize(){      return _write_pos-_read_pos;    }
    //获取读偏移
    char* GetReadPosition(){    return &_vv[_read_pos];     }
    //移动读偏移
    void MoveReadPosition(int len){  assert(len<=EnableReadSize());_read_pos+=len;  }
private:
    //找到一个'\n'字符位置
    char* FindCRLF(){  return (char*)memchr(&_vv[_read_pos],'\n',EnableReadSize());  }
    //获取写偏移
    char* GetWritePosition(){    return &_vv[_write_pos];     }
    //右侧剩余空间大小
    uint64_t RightExtraSpace(){     return _vv.size()-_write_pos;   } 
    //左侧剩余空间大小
    uint64_t LeftExtraSpace(){      return _read_pos;       }
    //清除Buffer缓冲区
    void Close(){   _read_pos=0;  _write_pos=0;     }
    //写入数据前，提前确保剩余空间足够
    void EnsureSpaceEnough(uint64_t size)
    {
        //右侧空间足够，无需操作
        if(size<=RightExtraSpace())return;
        //右侧+左侧空间足够，元素前移
        if(size>RightExtraSpace() && size<=RightExtraSpace()+LeftExtraSpace()){
            //元素前移
            uint64_t enable_size=EnableReadSize();
            std::copy(&_vv[_read_pos],&_vv[_write_pos],&_vv[0]);
            _read_pos=0,_write_pos=enable_size;
        }
        //右侧+左侧空间不够，需开辟空间
        else{
            _vv.resize(_vv.size()+size);
        }
    }
};

//Socket模块功能：封装套接字，简化接口
class Socket
{
private:
    int _sockfd;//对服务器来说，它是监听套接字，仅起到监听的功能，与客户端建立的连接fd是由accept得到的
public:         //对客户端来说，它是通信套接字，客户端可以直接向它send or recv数据
    Socket(int sockfd=-1):_sockfd(sockfd) {}
    ~Socket(){  Close();  }
    //关闭套接字
    void Close(){  close(_sockfd);  }
    //fd外裸接口
    int GetFd(){  return _sockfd;  }
    //创建套接字
    void CreateSocket()
    {
        //int socket(int domain,int type,int protocol);
        _sockfd=socket(AF_INET,SOCK_STREAM,0);
        if(_sockfd<0){
            Log(Error,"socket create fail,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"socketfd create successfully...%d",_sockfd);
    }
    //设置地址复用  
    void SetAddressReuse(){
        int opt=1;
        //int setsockopt(int sockfd,int level,int optname,const void* optval,socklen optlen);
        setsockopt(_sockfd,SOL_SOCKET,SO_REUSEADDR | SO_REUSEPORT,&opt,sizeof(opt));
    }
    //设置非阻塞式套接字
    void SetNonBlock()
    {
        //为防止对fd的属性覆盖，要先GET、再SET
        int fl=fcntl(_sockfd,F_GETFL);
        if(fl<0){
            Log(Error,"SetNonBlock socket fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(1);
        }
        fcntl(_sockfd,F_SETFL,fl | O_NONBLOCK);
        //Log(Debug,"SetNonBlock socket successfully...");
    }
    //绑定套接字
    void Bind(const std::string& ip,uint16_t port)
    {
        //int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));
        local.sin_family=AF_INET;
        local.sin_port=htons(port);
        local.sin_addr.s_addr=INADDR_ANY;
        if(bind(_sockfd,(const struct sockaddr*)&local,sizeof(local))<0){
            Log(Error,"socket bind fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"socket bind successfully...");
    }
    //监听套接字
    void Listen(int backlog)
    {
        //int listen(int sockfd,int backlog);
        if(listen(_sockfd,backlog)<0){
            Log(Error,"socket listen fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"socket listen successfully...");
    }
    //服务端接收来自客户端的连接
    int Accept(/*std::string& client_ip,uint16_t& client_port*/)
    {
        //int accept(int sockfd,struct sockaddr* addr,socklen_t* addrlen);
        struct sockaddr_in client;
        socklen_t len=sizeof(client);
        int recv_fd=accept(_sockfd,(struct sockaddr*)&client,&len);
        if(recv_fd<0){
            Log(Error,"socket from client accept fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"socket from client accept successfully...");
        char buf[64];
        //const char* inet_ntop(int AF,const void* src,char* dest,socklen_t len)
        // inet_ntop(AF_INET,&client.sin_addr,&client_ip[0],sizeof(client.sin_addr));//将网络字节序的整型ip转化成主机字节序的字符串ip
        // client_port=ntohs(client.sin_port);
        return recv_fd;//返回的是接收到的、与客户端新建立的连接fd
    }
    //客户端向服务端发送连接请求
    void Connect(const std::string& server_ip,uint16_t server_port)
    {
        struct sockaddr_in server;
        memset(&server,0,sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(server_port);
        //int inet_pton(int AF,const char* src,void* dest)
        inet_pton(AF_INET,server_ip.c_str(),&server.sin_addr);
        //int connect(int sockfd,const struct sockaddr* addr,sockaddr_t* len)
        if(connect(_sockfd,(struct sockaddr*)&server,sizeof(server))<0){
            Log(Error,"socket from server connect fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"socket from server connect successfully...");
    }
    //服务端接收来自客户端的数据
    ssize_t Read(int sockfd,void* buf,size_t len)
    {
        //ssize_t read(int fd,void* buf,size_t count);
        ssize_t ret=read(sockfd,buf,len);
        if(ret<0){
            Log(Error,"read data from client fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"read data from client successfully...");
        return ret;
    }
    //服务器向客户端发送数据
    ssize_t Write(int sockfd,const void* buf,size_t len)
    {
        //ssize_t write(int fd,const void* buf,size_t count);
        ssize_t ret=write(sockfd,buf,len);
        if(ret<0){
            Log(Error,"write data to client fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"write data to client successfully...");
        return ret;
    }
    //客户端接受服务端的响应
    ssize_t Recv(void* buf,size_t len,int flag=0)
    {
        //ssize_t recv(int sockfd,void* buf,size_t len,int flags)
        ssize_t ret=recv(_sockfd,buf,len,flag);//阻塞式接收数据
        if(ret<=0){
            //EAGAIN 当前socket的接收缓冲区没有数据了，仅在非阻塞条件下才会报该错误
            //EINTR  当前socket的阻塞等待被信息打断
            if(errno==EAGAIN || errno==EINTR)
                return 0;
            else if(ret!=0)
                Log(Error,"recv data fail,error code:%d,error info:%s",errno,strerror(errno));
            return -1;
        }
        return ret;
    }
    //非阻塞recv
    ssize_t RecvNonBlock(void* buf,size_t len)
    {
        return Recv(buf,len,MSG_DONTWAIT);//MSG_DONTWAIT表示非阻塞式接收数据
    }
    //客户端向服务端写入数据
    ssize_t Send(const void* datas,size_t len,int flag=0)
    {
        if(len==0)return 0;
        //ssize_t send(int sockfd,const void* buf,size_t len,int flag)
        ssize_t ret=send(_sockfd,datas,len,flag);//阻塞式发送数据
        if(ret<0){
            //EAGAIN 当前socket的发送缓冲区没有剩余空间了，无法向其中继续写入数据，仅在非阻塞条件下才会报该错误
            //EINTR  当前socket的阻塞等待被信息打断
            if(errno==EAGAIN || errno==EINTR)
                return 0;
            Log(Error,"client send fial,error code:%d,error info:%s",errno,strerror(errno));
            return -1;
        }
        return ret;
    }
    //创建一个服务端套接字
    int CreateOneServer(uint16_t port)
    {
        //1.先创建一个套接字
        CreateSocket();
        //2.对fd设置非阻塞属性
        //SetNonBlock();
        //3.对fd设置地址复用属性
        SetAddressReuse();
        //4.再绑定fd
        Bind("0.0.0.0",port);
        //5.监听套接字
        Listen(0);//可同时最多连接一个客户端

        //Log(Debug,"Server socket create successfully...");
        return _sockfd;
    }
    //建立一个客户端套接字
    int CreateOneClient(const std::string& server_ip,uint16_t server_port)
    {
        //1.先创建一个套接字
        CreateSocket();
        //2.对fd设置非阻塞属性
        //SetNonBlock();
        //与目标主机发起连接请求
        Connect(server_ip,server_port);
        //Log(Debug,"Client socket create successfully...");
        return _sockfd;
    }
};

class Epoller;
class EventLoop;
//channel模块功能:监管某一连接的具体触发事件，同时保存对应触发事件的处理方案
class Channel
{
    using calback_handle=std::function<void()>;//对各触发事件的处理方法
private:
    int _fd;                       //表示哪个连接
    EventLoop* _eventloop;         //用来对fd进行事件监控
    uint32_t _events;              //表示需要监控的事件，如:EPOLLIN、EPOLLOUT、EPOLLERR、EPOLLHUP
    uint32_t _trigger_events;      //表示已经触发的事件          
    //对各事件的处理方案
    calback_handle _read_handler;  //对读事件的处理方案
    calback_handle _write_handler; //对写事件的处理方案
    calback_handle _error_handler; //对错误事件的处理方案
    calback_handle _hangup_handler;//对挂断事件的处理方案
    calback_handle _random_handler;//对任意事件的处理方案
public:
    Channel(int fd,EventLoop* eventloop):_fd(fd),_eventloop(eventloop),_events(0),_trigger_events(0) { }
    //_fd外裸接口
    int GetFd(){  return _fd;  }
    //_events外裸接口
    uint32_t GetEvents(){  return _events;  }
    //设置_fd
    void SetFd(int fd){  _fd=fd;  }
    //设置触发事件
    void SetTriggerEvent(uint32_t trigger_events){  _trigger_events=trigger_events;  }
    //初始化各回调函数的处理方案
    void SetReadHandler(const calback_handle& cb)  {  _read_handler=cb;    }
    void SetWriteHandler(const calback_handle& cb) {  _write_handler=cb;   }
    void SetErrorHandler(const calback_handle& cb) {  _error_handler=cb;   }
    void SetHangupHandler(const calback_handle& cb){  _hangup_handler=cb;  }
    void SetRandomHandler(const calback_handle& cb){  _random_handler=cb;  }
public:
    //判断_epol是否监控了“读事件”
    bool Is_Read_Monitored(){  return _events & EPOLLIN;  }
    //判断_epol是否监控了“写事件”
    bool Is_Write_Monitored(){  return _events & EPOLLOUT;  }
    
    //让_epol监控“读事件”
    void Monitor_Read_Event(){  _events |= EPOLLIN;  RenewEvent();  }
    //让_epol监控“写事件”
    void Monitor_Write_Event(){  _events |= EPOLLOUT;  RenewEvent();  }

    //关闭_epol监控的“读事件”
    void Close_Read_Event(){  _events &= ~EPOLLIN;  RenewEvent();  }
    //关闭_epol监控的“写事件”
    void Close_Write_Event(){  _events &= ~EPOLLOUT;  RenewEvent();  }    
    //关闭_epol监控的所有事件
    void Close_All_Events(){  _events=0;  Remove_Socket();  }
    
    //移除_epol监控的_fd套接字
    void Remove_Socket();
    //更新_epol对fd的监管事件
    void RenewEvent();
    //事件处理————Channel的核心
    void Handler()
    {
        //判断是否有任意事件需要处理
        if(_random_handler) _random_handler();
        //判断是否有读事件需要处理
        if(((_trigger_events & EPOLLIN) || (_trigger_events & EPOLLRDHUP)|| (_trigger_events & EPOLLPRI)) && _read_handler){
            _read_handler();
        }
        //判断是否有写事件需要处理
        if((_trigger_events & EPOLLOUT) && _write_handler){
            _write_handler();
        }
        //判断是否有错误事件需要处理
        else if((_trigger_events & EPOLLERR) && _error_handler){
            _error_handler();
        }
        //判断是否有挂断事件需要处理
        else if((_trigger_events & EPOLLHUP) && _hangup_handler){
            _hangup_handler();
        }
    }
};

//Epoller模块，核心_epfd，负责监控所有的fd、返回就绪的fds。 fd————>Channel————>Handlers
//可以增添、修改和删除监控的fd，得到就绪的fds
class Epoller
{
private:
    int _epfd;//核心
    struct epoll_event _ready_fds[MAX_EVENTS]; //epoll_wait时，从中捞取的就绪fds，将就绪的fds放入_ready_fds中
    std::unordered_map<int,Channel*> _channel_hash;//记录epoll_wait中监控的fds
public:
    Epoller()
    {
        _epfd=epoll_create(128);
        if(_epfd<0){
            Log(Error,"epoll_create fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //Log(Debug,"epoll_create successfully,success code:%d,seccess info:%s",errno,strerror(errno));
    }
    ~Epoller(){  if(_epfd>0) close(_epfd);  }
    //更新（添加\修改）epoll监控的某一fd的某一事件
    void EpollUpdate(Channel* channel)
    {
        if(Is_Monitored(channel)==false){

            _channel_hash[channel->GetFd()]=channel;
            Update(channel,EPOLL_CTL_ADD);
        }
        else
		Update(channel,EPOLL_CTL_MOD);
    }
    //从epoll中删除指定的fd
    void EpollDel(Channel* channel)
    {
        auto iter=_channel_hash.find(channel->GetFd());
        if(iter!=_channel_hash.end()){
            _channel_hash.erase(iter);
            Update(channel,EPOLL_CTL_DEL);
        }   
    }
    //等待epoll中的就绪fds,开始监控
    void EpollWait(std::vector<Channel*>& vv)
    { 
        int ret=epoll_wait(_epfd,_ready_fds,MAX_EVENTS,-1);/*阻塞等待*/
        if(ret<0){
            if(errno==EINTR)return;
            Log(Error,"epoll_wait fial,error code:%d,error info:%s",errno,strerror(errno));
            exit(Error);
        }
        //为就绪的fd和trigger_events创建一个channel，并填充输出参数
        for(int i=0;i<ret;i++)
        {
            auto iter=_channel_hash.find(_ready_fds[i].data.fd);
            assert(iter!=_channel_hash.end());//若iter为空，则说明就绪的fd未被放入_channel_hash中
            iter->second->SetFd(_ready_fds[i].data.fd);//填充channel的fd
            iter->second->SetTriggerEvent(_ready_fds[i].events);//填充channel的就绪事件
            vv.push_back(iter->second);
        }
    }
private:
    //供类内部使用
    void Update(Channel* channel,int op)
    {
        int fd=channel->GetFd();

        struct epoll_event eet;
        eet.data.fd=fd;
        eet.events=channel->GetEvents();
	
        if(epoll_ctl(_epfd,op,fd,&eet)<0){
            Log(Error,"epoll_ctl_update fail,error code:%d,error info:%s",errno,strerror(errno));
       	    exit(Error);
       	}
    }
    //判断epoll是否监控了某fd
    bool Is_Monitored(Channel* channel)
    {
        auto iter=_channel_hash.find(channel->GetFd());
        if(iter==_channel_hash.end()) return false;
        return true;
    }
};

//模块功能：基于“时间轮盘”这一方案，实现对“连接”的超时处理和延时处理
using taskfunc=std::function<void()>;
using releasefunc=std::function<void()>;
class TimeTask{
    private:
    uint64_t _task_id;//标识每一个任务
    bool _is_canceled;//标识该任务是否被取消执行
    int _init_pos;    //初次执行的时间间隔
    int _timeout;     //每个任务的超时时间
    taskfunc _task_cb;//需要执行的任务————封装的核心
    releasefunc _release_cb;//来自timewheel模块的回调函数————清除timewheel中有关timetask的信息

    public:
    //初始化任务
    TimeTask(uint64_t id,int init_pos,int timeout,const taskfunc& cb,const releasefunc& release_cb)
    :_task_id(id),_is_canceled(false),_init_pos(init_pos),_timeout(timeout),_task_cb(cb),_release_cb(release_cb)
    {  /*std::cout<<"构造成功..."<<std::endl;*/  }
    //销毁任务——>执行任务, 当一个任务被销毁时，它要提醒timewheel，让_task_hash删除关于它的信息，这一功能同样是由一个回调函数完成的
    ~TimeTask(){ if(!_is_canceled) {  _release_cb();/*std::cout<<"nihao"<<std::endl;*/ _task_cb(); } }

    //id外裸接口
    uint64_t GetId(){return _task_id;} 
    //timeout外裸接口
    int GetTimeout(){return _timeout;}
    //init_pos外裸接口
    int GetInitPos(){return _init_pos;}
    //设置任务取消按钮
    void CancelTask(){  _is_canceled=true;  }
};

//定时器原理:Linux系统下，一切皆文件，定时器也是文件，所谓每隔一段时间“报时”，本质就是系统会每隔一段时间向timerfd文件写入一个八字节的数据
class TimeWheel
{
    using task_ptr=std::shared_ptr<TimeTask>;  //给_task_wheels使用
    using task_weak=std::weak_ptr<TimeTask>;   //给_task_hash使用，否则_task_hash中的任务会影响_task_wheels中智能指针的引用计数
private:
    int _pos;//滴答指针————走到哪里，就释放哪里的对象，即执行哪里的任务
    int _capacity;//确定轮盘大小
    std::vector<std::vector<task_ptr>> _task_wheels;//任务轮盘
    std::unordered_map<uint64_t,task_weak> _task_hash;//优化id遍历时间轮盘的时间复杂度 O(N)————>O(logN)

    int _timerfd; //控制任务的触发时间，即控制连接的超时时间
    EventLoop* _eventloop; //监控_timerfd，_timerfd一响应就会触发_eventloop
    std::unique_ptr<Channel> _timer_channel; //_eventloop触发_timerfd的载体
public:
    //初始化时间轮盘
    TimeWheel(EventLoop* eventloop):_pos(0),_capacity(60),_task_wheels(_capacity),\
    _eventloop(eventloop),_timerfd(CreateTimerFd()),_timer_channel(new Channel(_timerfd,_eventloop))
    {
        //设置_timer_channel读回调接口
        _timer_channel->SetReadHandler(std::bind(&TimeWheel::CarryTaskPerSec,this));
        //让_epoll监控_timerfd的可读事件
        _timer_channel->Monitor_Read_Event();
    }
    //销毁时间轮盘
    ~TimeWheel(){}
    //判断某一任务是否存在
    bool Is_Existed(uint64_t id){
        if(_task_hash.find(id)!=_task_hash.end())
            return true;
        return false;
    }
    //添加任务————线程保护，接口对外裸露
    void AddTaskInOneLoop(uint64_t id,int init_pos,int timeout,const taskfunc& task);
    //移除任务————线程保护，接口对外裸露
    void RemoveTaskInOneLoop(uint64_t id);
    //延时任务————线程保护，接口对外裸露
    void DelayTaskInOneLoop(uint64_t id);
private:
    //创建一个定时器
    static int CreateTimerFd(){
        int timerfd=timerfd_create(CLOCK_MONOTONIC,0);  //创建一个定时器：以系统启动时间作为基准值(定时器不会随系统时间改变而改变)   0-阻塞操作
        if(timerfd<0){
            Log(Error,"timerfd create fail...");
            abort();
        }
        struct itimerspec itime;
        itime.it_value.tv_sec=1;
        itime.it_value.tv_nsec=0;//1.0秒后触发一次“可读事件”
        itime.it_interval.tv_sec=1;
        itime.it_interval.tv_nsec=0;//第一次触发后，每隔1.0秒触发一次“可读事件”

        if(timerfd_settime(timerfd,0,&itime,NULL)<0){  //启动定时器
            Log(Error,"timerfd settime fail");
            abort();
        }
        return timerfd;
    }
    //把数据从timerfd读出来，关闭timerfd本次的读事件响应
    int TimerReadHandler(){
        uint64_t res;//res表示定时器执行的次数
        int ret=read(_timerfd,&res,sizeof(res));//注意：res的大小必须是8字节
        if(ret<0){
            if(ret==EINTR || ret==EAGAIN) return 0;//被信号中断或没有数据可读
            Log(Error,"read data from _timerfd fail...");
            abort();
        }
	return res;
    }
    //转动时间轮盘————执行任务
    void CarryStep(){
        _task_wheels[_pos].clear();//释放_pos位置的所有task_ptr，timetask析构，cb被动执行
        _pos=(_pos+1)%_capacity;
        // static int i=1;
        // std::cout<<"时间轮盘:"<<i<<std::endl; //？？timerfd应该每秒都触发一次可读事件，为啥仅显示了最初的一次？？
    }
    //每秒执行一次任务
    void CarryTaskPerSec(){
        int count=TimerReadHandler();//将定时器中的数据读取出来
	for(int i=0;i<count;i++)
        	CarryStep();//执行任务
    }
    //向timewheel添加任务
    void AddTask(uint64_t id,int init_pos,int timeout,const taskfunc& task)
    {
        //1.由于RemoveTask参数由this，所以需要bind；2.id已经被bind，故调用release_cb时无需再次传参。注意这里release_cb和RemoveTask的类型，bind后的函数参数类型！！！
        task_ptr new_task(new TimeTask(id,init_pos,timeout,task,std::bind(&TimeWheel::RemoveTask,this,id)));//??? ————为啥用=赋值不行
        
        _task_wheels[(_pos+init_pos)%_capacity].push_back(new_task);
        _task_hash[id]=task_weak(new_task);
    }
    //从timewheel中移除任务
    void RemoveTask(uint64_t id)
    {
        //删除前，先判断id是否存在
        auto iter=_task_hash.find(id);
        if(iter!=_task_hash.end())
        {
            task_ptr tmp_ptr=iter->second.lock();//获取weak_ptr指向的shared_ptr
            if(tmp_ptr)tmp_ptr->CancelTask();//执行定时销毁任务时，iter->second会先被销毁，所以需要判断一下
            _task_hash.erase(iter);
        }
        std::cout<<"task_weak remove from _tast_arr successfully..."<<std::endl;
    }
    //延时任务————本质就是，在时间轮盘中再添加一个id相同的task_ptr指针，让其引用计数++，使得timetask延时释放，即任务延时执行
    void DelayTask(uint64_t id)
    {
        //延时前，先判断id是否存在
        auto iter=_task_hash.find(id);
        if(iter!=_task_hash.end())
        {
            task_ptr buf_task=iter->second.lock();//由weak_ptr得到shared_ptr的接口
            _task_wheels[(_pos+buf_task->GetTimeout())%_capacity].push_back(buf_task);
            //std::cout<<"延时成功..."<<std::endl;
        }
        else std::cout<<id<<"号任务延时失败..."<<std::endl;
    }
};

//1.EventLoop模块对Epoller模块接口进行了一个简单的封装
//2.EventLoop能够解决外界函数调用时的线程安全问题————任务队列 + 锁
//3.每个线程与EventLoop一一对应
//4.对连接超时触发自动断开机制
class EventLoop
{
    using Factor=std::function<void()>;
private:
    std::thread::id _id; //线程id，用于标识线程
    int _eventfd;//先wait，后执行任务，但wait可能阻塞住，_eventfd可以唤醒阻塞的wait
    Channel _event_channel;//对_eventfd的接口进行封装，同时确保_eventfd能够被_epoll监控

    Epoller _epoll;//事件监控 + 处理 + 控制任务列队的执行

    std::vector<Factor> _tasks;//任务队列
    std::mutex _mutex;//锁————用于:1.外界任务加入任务队列时  2.任务队列的执行

    TimeWheel _timewheel; //实现连接超时时的自动断开功能
private:
    static int CreateEventFd(){
        //EFD_CLOEXEC：禁止进程赋值    EFD_NONBLOCK：启动非阻塞属性
        int efd=eventfd((uint64_t)0,EFD_CLOEXEC | EFD_NONBLOCK);
        if(efd<0){
            Log(Error,"eventfd create fail...");
            abort();
        }
        return efd;
    }
    void EventReadHandler(){
        uint64_t res;
        int ret=read(_eventfd,&res,sizeof(res));
        if(ret<0){
            if(ret==EINTR || ret==EAGAIN)return;
            Log(Error,"read data from eventfd fail...");
            abort();
        }
    }
public:
    EventLoop():_eventfd(CreateEventFd()),_event_channel(_eventfd,this),_timewheel(this),_id(std::this_thread::get_id())
    {
        //初始化_event_channel的read接口
        _event_channel.SetReadHandler(std::bind(&EventLoop::EventReadHandler,this));
        //使_eventfd被_epoll监控
        _event_channel.Monitor_Read_Event();
    }
    void RunAllTask()
    {
        //将“对每个任务各加一次锁” 优化成 “对任务队列中的所有任务仅加一次锁”，以减少加锁、解锁次数
        std::vector<Factor> bufs;
        {
            std::unique_lock<std::mutex> lock;
            bufs.swap(_tasks);
        }
        //执行bufs中的任务
        for(auto& func:bufs) func();
    }
    //1.开始监控   2.事件处理   3.执行任务队列中的任务
    void Start()
    {
        while(1)
        {
            //1.开始监控
            std::vector<Channel*> actives;
            _epoll.EpollWait(actives);
            //2.事件处理
            for(auto& channel:actives) channel->Handler();
            //3.执行任务队列中的任务
            RunAllTask();
        }
    }
    
    //判断执行外界函数线程的id是否与_id相同
    bool Is_Id_Equal(){  return _id==std::this_thread::get_id();  }
    //若执行外界函数线程的id与_id相同，则直接执行;若否，则加入任务队列
    void RunFuncInLoop(const Factor& cb){  
        if(Is_Id_Equal()) cb(); else _tasks.push_back(cb);  
    }

    //封装Epoller的EpollUpdate接口
    void EpollUpdate(Channel* channel){  _epoll.EpollUpdate(channel);  }
    //封装Epoller的EpollDel接口
    void EpollDel(Channel* channel){  _epoll.EpollDel(channel);  }
    //添加定时器任务
    void AddTimerTask(uint64_t id,int init_pos,int timeout,const taskfunc& task){  
        _timewheel.AddTaskInOneLoop(id,init_pos,timeout,task);
    }
    //移除任务————线程保护，接口对外裸露
    void RemoveTimerTask(uint64_t id){  _timewheel.RemoveTaskInOneLoop(id);  }
    //延时任务————线程保护，接口对外裸露
    void DelayTaskInOneLoop(uint64_t id){  _timewheel.DelayTaskInOneLoop(id);  }
    //判断某一任务是否存在
    bool Is_Existed(uint64_t id){ return  _timewheel.Is_Existed(id);  }
};

void Channel::RenewEvent(){  _eventloop->EpollUpdate(this);  }
void Channel::Remove_Socket(){  _eventloop->EpollDel(this);  }
//向timewheel添加任务
void TimeWheel::AddTaskInOneLoop(uint64_t id,int init_pos,int timeout,const taskfunc& task){  
    _eventloop->RunFuncInLoop(std::bind(&TimeWheel::AddTask,this,id,init_pos,timeout,task));  }
//移除任务————线程保护，接口对外裸露
void TimeWheel::RemoveTaskInOneLoop(uint64_t id){  
    _eventloop->RunFuncInLoop(std::bind(&TimeWheel::RemoveTask,this,id));  }
//延时任务————线程保护，接口对外裸露
void TimeWheel::DelayTaskInOneLoop(uint64_t id){  
    _eventloop->RunFuncInLoop(std::bind(&TimeWheel::DelayTask,this,id));
}

class Any
{
private:
    class base
    {
    public:
        virtual ~base(){}
        virtual const std::type_info& GetType() = 0;
        virtual base* clone() = 0;
    };
    template<class T>
    class derive:public base 
    {
    public:
        T _val;
    public:
        derive(const T& val):_val(val) {}

        const std::type_info& GetType(){  return typeid(T);  }

        derive* clone(){    return new derive<T>(_val);    }
    };
private:
    base* _ptr; //多态的作用，就是为了这里的_ptr类型不用显示实例化，即通过父类指针绕过了子类模版类的实例化
private:
    Any& swap(Any& ay){  std::swap(ay._ptr,_ptr);  return *this; }
public:
    Any():_ptr(nullptr){}
    template<class T>
    Any(const T& data) :_ptr(new derive<T>(data)) {} //实例化一个空对象
    Any(const Any& ay):_ptr(ay._ptr?ay._ptr->clone():nullptr){} //用一个Any对象，实例化另一个Any对象
    ~Any(){  delete _ptr;  }

    template<class T>
    Any& operator=(const T& data){   Any(data).swap(*this); /*优化点————移动拷贝*/  return *this;  }
    Any& operator=(Any ay){   swap(ay);  return *this;   } //Any a=2; Any b = "abc";  a=b;  


    template<class T>
    T* GetAddress(){  if(typeid(T)==_ptr->GetType()) return &(((derive<T>*)_ptr)->_val); else return nullptr; }

};

class Connection;
typedef enum{ DISCONNECTED,CONNECTING,CONNECTED,DISCONNECTING}ConnStatus; 
using PtrConnection=std::shared_ptr<Connection>;

//Connection模块，用于完成对整个链接（主要包括：fd、事件、回调函数、超时处理）的管理，主要功能如下:
//1.向对方发送数据  2.断开链接  3.启动超时连接自动断开机制  4.取消超时连接自动断开机制  5.协议切换
class Connection:public std::enable_shared_from_this<Connection>
{
    using Connection_Established_Calback=std::function<void(const PtrConnection&)>;     //连接建立成功后的处理方案
    using Messege_Received_Calback=std::function<void(const PtrConnection&,Buffer*)>;   //收到消息后的处理方案
    using Connection_Closed_Calback=std::function<void(const PtrConnection&)>;  //连接断开后的处理方案
    using Any_Event_Calback=std::function<void(const PtrConnection&)>;          //任意事件的回调函数
private:
    int _conn_id;//连接id，用于表示每个连接的唯一性

    Socket _sock;//管理套接字的模块
    EventLoop* _eventloop;//监控sockfd、提供超时处理机制、提供线程安全保护
    Channel _sock_channel;//sockfd的某一事件触发监控后，对相应事件的处理

    Any _context;//存放协议上下文
    ConnStatus _connStatus;//标识连接状态
    bool _enable_inactive_release;//标识该连接是否启动“非活跃连接”的超时销毁机制

    Buffer _recv_buffer;  //接收缓冲区，存放从sockfd读取的数据
    Buffer _send_buffer;  //发送缓冲区，存放即将写入sockfd的数据
    //处理上层传来的回调函数
    Connection_Established_Calback _connect_established_calback;
    Messege_Received_Calback  _messege_received_calback;
    Connection_Closed_Calback _connect_closed_calback;
    Connection_Closed_Calback _ser_close_calback;               //用来移除上层对该连接的管理的回调函数
    Any_Event_Calback  _any_event_calback;
public:
    Connection(int conn_id,EventLoop* eventloop,int fd) :_conn_id(conn_id),_eventloop(eventloop)
    ,_sock(fd),_sock_channel(_sock.GetFd(),_eventloop),_connStatus(CONNECTING),_enable_inactive_release(false)
    {
        _sock_channel.SetReadHandler(std::bind(&Connection::ReadHandler,this));
        _sock_channel.SetWriteHandler(std::bind(&Connection::WriteHandler,this));
        _sock_channel.SetErrorHandler(std::bind(&Connection::ErrorHandler,this));
        _sock_channel.SetHangupHandler(std::bind(&Connection::HangupHandler,this));
        _sock_channel.SetRandomHandler(std::bind(&Connection::RandomHandler,this));
    }

    ~Connection(){};
    //获取sockfd
    int GetFd(){  return _sock.GetFd();  }
    //获取协议
    Any* GetContext(){  return &_context;  }
    //设置协议
    void SetContext(const Any& context){  _context=context;  }
    //是否处于CONNECTED状态
    bool Is_Connected(){  return _connStatus==CONNECTED;  }

    //设置连接建立成功后的回调函数
    void SetConnEstablishedCalback(const Connection_Established_Calback& cb){  _connect_established_calback=cb;  }
    //设置连接断开后的回调函数
    void SetConnClosedCalback(const Connection_Closed_Calback& cb){  _connect_closed_calback=cb;  }
    //设置连接收到信息后的回调函数
    void SetMessegeReceivedCalback(const Messege_Received_Calback& cb){  _messege_received_calback=cb;  }
    //设置上层传来的任意事件回调函数
    void SetAnyEventCalback(const Any_Event_Calback& cb){  _any_event_calback=cb;  }
    //设置移除上层对连接管理的回调函数
    void SetSerCloseCalback(const Connection_Closed_Calback& cb){  _ser_close_calback=cb;  }

    //向sockfd写入上层传来的数据，而sockfd什么时候向对方发送，需要触发sockfd的“写事件”
    void Send(const void* buf,size_t len){  
        Buffer tmp;
        tmp.WriteData(buf,len);
        _eventloop->RunFuncInLoop(std::bind(&Connection::SendInLoop,this,std::move(tmp)));  
        }
    //断开链接---对用户而言，实际是否断开，需要判断缓冲区内是否仍有数据需要处理
    void Close(){  _eventloop->RunFuncInLoop(std::bind(&Connection::CloseInLoop,this));  }
    //释放资源
    void Release() {  _eventloop->RunFuncInLoop(std::bind(&Connection::ReleaseInLoop,this)); }
    //启动非活跃连接超时销毁机制
    void EnableInactiveRelease(int sec){  _eventloop->RunFuncInLoop(std::bind(&Connection::EnableInactiveReleaseInLoop,this,sec));  }
    //关闭非活跃连接超时销毁机制
    void CancelInactiveRelease(){  _eventloop->RunFuncInLoop(std::bind(&Connection::CancelInactiveReleaseInLoop,this));  }
    //开启事件监控机制
    void EnableEventMonitor(){  ConnectionEstablishedInLoop();  }
    //协议切换
    void ReflushProtocol(const Any context,const Connection_Established_Calback& conn_estbsd_cb,\
    const Connection_Closed_Calback& conn_clsd_cb,const Messege_Received_Calback& meg_recv_cb,\
    const Any_Event_Calback& any_event_cb,const Connection_Closed_Calback& ser_close_calback){
        _eventloop->RunFuncInLoop(std::bind(&Connection::ReflushProtocolInLoop,this,context,\
        conn_estbsd_cb,conn_clsd_cb,meg_recv_cb,any_event_cb,ser_close_calback));
    }
private:
    // channel管理的事件回调
    // 当监控触发“读事件”后的读回调函数,需要将sockfd中的数据读到recv_buffer中，并交给messege_cb处理
    void ReadHandler()
    {
        //将sockfd中的数据读到bufs中
        char bufs[65536];
        int ret=_sock.RecvNonBlock(bufs,sizeof(bufs));
        if(ret<0){
            //读取数据出错了,判断_recv_buffer中是否仍有数据需要处理，若无，则“关闭连接”
            CloseInLoop();//关闭连接
            return;
        }
        //将sockfd中的数据读到recv_buffer中
        _recv_buffer.WriteData(bufs,ret);
        if(_recv_buffer.EnableReadSize()>0) 
            _messege_received_calback(shared_from_this(),&_recv_buffer);//读事件处理
    }
    //当监控触发“写事件”后的写回调函数,将out_buffer中的数据通过sockfd发送给对方
    void WriteHandler()
    {
        int ret=_sock.Send(_send_buffer.GetReadPosition(),_send_buffer.EnableReadSize());
        if(ret<0){
            //写入失败
            if(_recv_buffer.EnableReadSize()>0) 
                _messege_received_calback(shared_from_this(),&_recv_buffer);//读事件处理
            return Release();//关闭连接————实际的关闭释放操作
        }
        _send_buffer.MoveReadPosition(ret);

        //如果发送缓冲区已经没有数据了，就不要再继续监控“写事件”了，否则会一直触发“写事件”
        if(_send_buffer.EnableReadSize()==0){
            _sock_channel.Close_Write_Event();//关闭写事件监控
            //如果该连接处于正在关闭状态，那么发送完数据之后，直接关闭该连接
            if(_connStatus==DISCONNECTING)
                Release();//没有数据需要处理了，可以将连接关闭了
        }
    }
    //当监控触发“挂断事件”后的挂断回调函数,关闭连接
    void HangupHandler(){
        //判断接收缓冲区是否仍有数据待处理
        if(_recv_buffer.EnableReadSize()>0)
            _messege_received_calback(shared_from_this(),&_recv_buffer);
        
        Release();//释放连接
    }
    //当监控触发“错误事件”后的错误事件回调函数，关闭连接
    void ErrorHandler(){
        HangupHandler();
    }
    //当监控触发“任意事件”后的任意事件回调函数,需要刷新连接活跃度，并执行上层回调函数
    void RandomHandler(){
        if(_enable_inactive_release==true)
            _eventloop->DelayTaskInOneLoop(_conn_id);//存在则刷新活跃度
        if(_any_event_calback)
            _any_event_calback(shared_from_this());//执行上层回调函数
    }
    
    //连接建立完成后，处于CONNECTING状态，此时，需要启动“读事件监控”，并调用上层的回调函数
    void ConnectionEstablishedInLoop(){
        //1.修改连接状态
        assert(_connStatus==CONNECTING);
        _connStatus=CONNECTED;
        //2.启动读事件监控
        _sock_channel.Monitor_Read_Event();
        //3.调用上层的回调函数
        if(_connect_established_calback)
            _connect_established_calback(shared_from_this());
    }
    //实际连接释放的接口
    void ReleaseInLoop(){
        //1.修改连接状态
        _connStatus=DISCONNECTED;
        //2.移除连接的事件监控
        _sock_channel.Close_All_Events();
        //std::cout<<"!!!"<<std::endl;
        //3.如果定时器任务中还有该连接，则取消该连接的超时销毁机制
        if(_eventloop->Is_Existed(_conn_id))
            CancelInactiveReleaseInLoop();   
        //4.关闭文件描述符
        _sock.Close();
        //5.移除上层对该连接的管理
        if(_connect_closed_calback)_connect_closed_calback(shared_from_this());
        if(_ser_close_calback) _ser_close_calback(shared_from_this());
    }
    
    /*确保操作线程安全*/
    //这个并不是实际的数据发送接口，而是将待发送的数据写入_send_buffer，并启动“写事件”监控
    void SendInLoop(Buffer& buf){
        if(_connStatus==DISCONNECTED)return;
        //将待发送的数据写入_send_buffer
        _send_buffer.WriteData(buf.GetReadPosition(),buf.EnableReadSize());
        //启动“写事件”监控
        _sock_channel.Monitor_Write_Event();
    }
    //这个并不是实际的释放连接接口  1.将连接状态改成正在关闭状态  2.处理接收、发送缓冲区内的数据  
    void CloseInLoop(){
        //1.将连接状态改成正在关闭状态
        _connStatus=DISCONNECTING;
        //2.处理接收缓冲区内的数据
        if(_recv_buffer.EnableReadSize()>0 && _messege_received_calback)
            _messege_received_calback(shared_from_this(),&_recv_buffer);
        //2.处理发送缓冲区内的数据
        if(_send_buffer.EnableReadSize()>0){
            _sock_channel.Monitor_Write_Event();//启动“写事件”监控
        }
        if(_send_buffer.EnableReadSize()==0)
            ReleaseInLoop();//关闭连接
    }
    //启动非活跃连接超时释放机制
    void EnableInactiveReleaseInLoop(int sec){
        //1.修改_Enable_Inactive_Release标识
        _enable_inactive_release=true;
        //2.若非活跃连接销毁任务已存在，则刷新
        if(_eventloop->Is_Existed(_conn_id)==1){
            _eventloop->DelayTaskInOneLoop(_conn_id);
        }
        //3.若非活跃连接销毁任务未添加，则添加
        else _eventloop->AddTimerTask(_conn_id,sec,sec,std::bind(&Connection::ReleaseInLoop,this));
    }
    //取消非活跃连接超时释放机制
    void CancelInactiveReleaseInLoop(){
        _enable_inactive_release=false;
        if(_eventloop->Is_Existed(_conn_id)==1){
            _eventloop->RemoveTimerTask(_conn_id);
        }
    }
    //切换上下文协议
    void ReflushProtocolInLoop(const Any context,const Connection_Established_Calback& conn_estbsd_cb,\
    const Connection_Closed_Calback& conn_clsd_cb,const Messege_Received_Calback& meg_recv_cb,\
    const Any_Event_Calback& any_event_cb,const Connection_Closed_Calback& ser_close_cb)
    {
        _context=context;
        _connect_established_calback=conn_estbsd_cb;
        _connect_closed_calback=conn_clsd_cb;
        _messege_received_calback=meg_recv_cb;
        _any_event_calback=any_event_cb;
        _ser_close_calback=ser_close_cb;
    }
};

//功能如下：
//1.创建一个监听套接字
//2.启动读事件监控
//3.事件触发后，获取新连接，至于对新连接如何处理，由上层设置的回调函数决定
class Acceptor
{
    //获取到新连接后，需要对新链接进行处理，但如何处理，是由上层模块决定的
    using NewConnectionReceived=std::function<void(int)>;
private:
    Socket _lst_sock;//监听套接字
    EventLoop* _eventloop;//用于监控lst_sockfd
    Channel _lst_channel;//回调lst_sockfd的事件管理函数
    NewConnectionReceived _new_conn_recvd; 
private:
    int CreateListenSockFd(int port){
        int lst_sockfd=_lst_sock.CreateOneServer(port);
        assert(lst_sockfd>0);
        return lst_sockfd;
    }
    //获取新连接
    void ReadHandler(){
        int newfd=_lst_sock.Accept();
        if(newfd<0)return;
        if(_new_conn_recvd)_new_conn_recvd(newfd);
    }
public:
    Acceptor(EventLoop* eventloop,uint16_t port)
    :_lst_sock(CreateListenSockFd(port)),_eventloop(eventloop),_lst_channel(_lst_sock.GetFd(),eventloop){
        //设置_lst_sock的读事件回调
        _lst_channel.SetReadHandler(std::bind(&Acceptor::ReadHandler,this));
    }
    //向外界提供设置_new_conn_recvd回调函数的接口
    void SetNewConnRecvd(const NewConnectionReceived& cb){  _new_conn_recvd=cb;  }
    //启动事件监控
    void Monitor_New_Link(){  _lst_channel.Monitor_Read_Event();  }
};

//LooopThread模块功能:
//1.创建从属线程，并将eventloop与从属线程一一联系起来
class LoopThread
{
private:
    std::condition_variable _cond;
    std::mutex _mutex;      //使用_cond和_mutex，是为了解决上层在eventloop创建前调用GetEventLoop函数的问题
    EventLoop* _eventloop;  //必须先创建线程，在实例化eventloop
    std::thread _thread;    //eventloop对应的线程
private:
    //线程入口函数:1.创建线程   2.在线程内部实例化一个eventloop   3.eventloop开始Start
    void ThreadEntry()
    {
        EventLoop eventloop;
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _eventloop=&eventloop;
            _cond.notify_all();
        }
        eventloop.Start();
    }
public:
    //创建线程
    LoopThread():_eventloop(nullptr),_thread(std::thread(&LoopThread::ThreadEntry,this)){}

    EventLoop* GetEventLoop()
    {
        //由于_eventloop可能会被多个不同的线程访问，所以各线程获取_eventloop时，要用互斥锁
        EventLoop* eventloop;
        {
            std::unique_lock<std::mutex> lock(_mutex);//用lock的生命周期来加锁
            _cond.wait(lock,[&](){  return _eventloop!=nullptr;  });//当_eventloop仍未实例化时，阻塞等待
            eventloop=_eventloop;
        }
        return eventloop;
    }
};

class LoopThreadPool
{
private:
    int _thread_count;
    int _next_thread;
    std::vector<LoopThread*> _threads; //从属线程
    EventLoop* _base_thread;           //主线程
public:
    LoopThreadPool(EventLoop* eventloop,int count):_thread_count(count),_next_thread(0),_threads(_thread_count),_base_thread(eventloop)
    {
        if(_thread_count>0)
        {
            for(int i=0;i<_thread_count;i++)
            {
                _threads[i]=new LoopThread();
            }
        }
    }
    EventLoop* GetOneThread()
    {
        if(_thread_count==0)return _base_thread;

        _next_thread=(_next_thread+1)%_thread_count;
        return _threads[_next_thread]->GetEventLoop();
    }
};

class TcpServer
{
    using Connection_Established_Calback=std::function<void(const PtrConnection&)>;     //连接建立成功后的处理方案
    using Messege_Received_Calback=std::function<void(const PtrConnection&,Buffer*)>;   //收到消息后的处理方案
    using Connection_Closed_Calback=std::function<void(const PtrConnection&)>;  //连接断开后的处理方案
    using Any_Event_Calback=std::function<void(const PtrConnection&)>;          //任意事件的回调函数
private:
    EventLoop _basethread;                         //主线程
    LoopThreadPool _threads;                       //从属线程池
    std::unordered_map<int,PtrConnection> _conns;  //管理所有连接
    int _conn_id;                                  //连接索引
    Acceptor _acceptor;                            //监听套接字

    //处理组件使用者传来的回调函数
    Connection_Established_Calback _connect_established_calback;
    Messege_Received_Calback  _messege_received_calback;
    Connection_Closed_Calback _connect_closed_calback;
    Connection_Closed_Calback _ser_close_calback;               //用来移除_conns对该连接的管理的回调函数
    Any_Event_Calback  _any_event_calback;
private:
    void RemoveFromHash(int id)
    {
        auto iter=_conns.find(id);
        if(iter!=_conns.end())
        {
            _conns.erase(iter);
            std::cout<<"Romove PtrConnection from _conns successfully"<<std::endl;
        }
    }
    void acceptor(int new_fd,int timeout)
    {
        //2.为新fd创建PtrConnection对象
        PtrConnection com_conn(new Connection(_conn_id,_threads.GetOneThread(),new_fd));
        //3.为com_conn填充回调函数
        com_conn->SetMessegeReceivedCalback(_messege_received_calback);
        com_conn->SetConnEstablishedCalback(_connect_established_calback);
        com_conn->SetSerCloseCalback(std::bind(&TcpServer::RemoveFromHash,this,_conn_id));
        //4.开启超时断开机制
        com_conn->EnableInactiveRelease(timeout);
        //5.连接建立成功、开启事件监控
        com_conn->EnableEventMonitor();
        //6.将新连接放到“用于管理所有链接的数据结构”中
        _conns[_conn_id]=com_conn;

        _conn_id++;
    }
public:
    TcpServer(int port,int count,int timeout=10):_threads(&_basethread,count),_conn_id(0),_acceptor(&_basethread,8888)
    {
        _acceptor.SetNewConnRecvd(std::bind(&TcpServer::acceptor,this,std::placeholders::_1,timeout));
        _acceptor.Monitor_New_Link();
    }

    //设置连接建立成功后的回调函数
    void SetConnEstablishedCalback(const Connection_Established_Calback& cb){  _connect_established_calback=cb;  }
    //设置连接断开后的回调函数
    void SetConnClosedCalback(const Connection_Closed_Calback& cb){  _connect_closed_calback=cb;  }
    //设置连接收到信息后的回调函数
    void SetMessegeReceivedCalback(const Messege_Received_Calback& cb){  _messege_received_calback=cb;  }
    //设置上层传来的任意事件回调函数
    void SetAnyEventCalback(const Any_Event_Calback& cb){  _any_event_calback=cb;  }
    //主线程开始监控
    void Start(){  _basethread.Start();  }
};
